package com.cherry.androidcode.helper

import android.widget.ImageView
import androidx.collection.LongSparseArray
import androidx.fragment.app.FragmentActivity
import androidx.recyclerview.widget.RecyclerView
import com.cherry.androidcode.entity.ImageBean
import com.cherry.androidcode.helper.ImageViewerHelper.TransitionViewsRef.KEY_MAIN
import com.cherry.androidcode.image.GlideApp
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
import com.github.iielse.imageviewer.ImageViewerBuilder
import com.github.iielse.imageviewer.core.DataProvider
import com.github.iielse.imageviewer.core.ImageLoader
import com.github.iielse.imageviewer.core.Photo
import com.github.iielse.imageviewer.core.Transformer
import com.github.iielse.imageviewer.widgets.video.ExoVideoView2

/**
 * @author DongMS
 * @since 2020-09-23
 */
object ImageViewerHelper {

    fun provideImageViewerBuilder(context: FragmentActivity, clickedData: String): ImageViewerBuilder {
        val imageBean = ImageBean(clickedData)

        return ImageViewerBuilder(
                context = context,
                initKey = imageBean.id(), // 用于定位被点击缩略图变化大图后初始化所在位置.以此来执行过渡动画.
                dataProvider = MyDataProvider(imageBean), // 浏览数据源的提供者.支持一次性给全数据或分页加载.
                imageLoader = MyImageLoader(), // 实现对数据源的加载.支持自定义加载数据类型，加载方案
                transformer = MyTransformer() // 以photoId为标示，设置过渡动画的'配对'.
        )
    }


    class MyDataProvider(private val imageBean: ImageBean) : DataProvider {
        override fun loadInitial(): List<Photo> {
            return listOf(imageBean) // 返回查看大图对应的数据源.若不需要分页可再次一次性返回所有数据源.
        }
    }

    class MyImageLoader : ImageLoader {
        /**
         * 根据自身photo数据加载图片.可以使用其它图片加载框架.
         */
        override fun load(view: ImageView, data: Photo, viewHolder: RecyclerView.ViewHolder) {

            GlideApp.with(view).load((data as ImageBean).url).into(view)
        }

        override fun load(exoVideoView: ExoVideoView2, data: Photo, viewHolder: RecyclerView.ViewHolder) {
            super.load(exoVideoView, data, viewHolder)
        }

        override fun load(subsamplingView: SubsamplingScaleImageView, data: Photo, viewHolder: RecyclerView.ViewHolder) {
            super.load(subsamplingView, data, viewHolder)
        }

        /**
         * 根据自身photo数据加载超大图.subsamplingView数据源需要先将内容完整下载到本地.需要注意生命周期
         */
//        override fun load(subsamplingView: SubsamplingScaleImageView, data: Photo, viewHolder: RecyclerView.ViewHolder) {
//            val it = (data as? MyData?)?.url ?: return
//            subsamplingDownloadRequest(it)
//                    .subscribeOn(Schedulers.io())
//                    .observeOn(AndroidSchedulers.mainThread())
//                    .doOnSubscribe { findLoadingView(viewHolder)?.visibility = View.VISIBLE }
//                    .doFinally { findLoadingView(viewHolder)?.visibility = View.GONE }
//                    .doOnNext { subsamplingView.setImage(ImageSource.uri(Uri.fromFile(it))) }
//                    .doOnError { toast(it.message) }
//                    .subscribe().bindLifecycle(subsamplingView)
//        }

//        private fun subsamplingDownloadRequest(url: String): Observable<File> {
//            return Observable.create {
//                try {
//                    it.onNext(GlideApp.with().downloadOnly().load(url).submit().get())
//                    it.onComplete()
//                } catch (e: java.lang.Exception) {
//                    if (!it.isDisposed) it.onError(e)
//                }
//            }
//        }
//
//        private fun findLoadingView(viewHolder: RecyclerView.ViewHolder): View? {
//            return viewHolder.itemView.findViewById<ProgressBar>(R.id.loadingView)
//        }
    }


    class MyTransformer : Transformer {
        override fun getView(key: Long): ImageView? = TransitionViewsRef.provideTransitionViewsRef(KEY_MAIN)[key]
    }

    /**
     * 维护Transition过渡动画的缩略图和大图之间的映射关系. 需要在Activity/Fragment释放时刻.清空此界面的View引用
     * (这里是比较随便的一种写法.没有说必须这样写.大家可以用更好的写法.谢谢)
     */
    object TransitionViewsRef {
        private val map = mutableMapOf<String, LongSparseArray<ImageView>?>() // 可能有多级页面
        const val KEY_MAIN = "page_main"

        fun provideTransitionViewsRef(key: String): LongSparseArray<ImageView> {
            return map[key] ?: LongSparseArray<ImageView>().also { map[key] = it }
        }

        // invoke when activity onDestroy or fragment onDestroyView
        fun releaseTransitionViewRef(key: String) {
            map[key] = null
        }
    }
}